﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

#if net35
namespace System.Linq
{
	public static class ParallelEnumerable
	{
		public class ParallelQuery<TSource> {
			private IEnumerable<TSource> source;

			public ParallelQuery(IEnumerable<TSource> source)
			{
				this.source = source;
			}

			public IEnumerable<TResult> Select<TResult>(Func<TSource, TResult> selector) {

				var ev = new ManualResetEvent(false);
				var queue = new Queue<TResult>();
				int count = 0;
				source.All(s =>
				{
					ThreadPool.QueueUserWorkItem(new WaitCallback((o) =>
					{
						var res = selector(s);
						lock (ev) {
							queue.Enqueue(res);
							ev.Set();
						}
					}));
					count++;
					return true;
				});
				while (count != 0) {
					ev.WaitOne();
					lock(ev){
						while (queue.Count != 0)
						{
							yield return queue.Dequeue();
							count--;
						}
					}
				}
			}
		}

		public static IEnumerable<TResult> Select<TSource, TResult>(this ParallelQuery<TSource> source, Func<TSource, TResult> selector)
		{
			return source.Select(selector);
		}
		
		public static ParallelQuery<T> AsParallel<T>(this IEnumerable<T> source) {
			return new ParallelQuery<T>(source);
		}
	}
}
#endif